﻿#pragma once

#include <xy/geom/vec.h>

namespace xy
{

namespace render
{

struct mesh_material
{
    std::string name;
    geom::vec3f Ka; // 环境光
    geom::vec3f Kd; // 漫反射
    geom::vec3f Ks; // 镜面反射
    geom::vec3f Ke; // 自发光
    geom::vec3f Kt; // 透射
    float Ns;       // 高光系数
    float Ni;       // 折射指数
    geom::vec3f Tf; // 透射滤镜
    float d;        // 不透明度
    int illum;      // 光照模型

    std::string map_Ka;   // 环境光贴图
    std::string map_Kd;   // 漫反射贴图
    std::string map_Ks;   // 镜面反射贴图
    std::string map_Ke;   // 自发光贴图
    std::string map_Kt;   // 透射贴图
    std::string map_Ns;   // 高光系数贴图
    std::string map_Ni;   // 折射指数贴图
    std::string map_d;    // 不透明度贴图
    std::string map_bump; // 凹凸贴图
};

struct mesh
{
  private:
    struct _impl
    {
        std::vector<geom::vec3f> vertices;
        std::vector<geom::vec3f> normals;
        std::vector<geom::vec2f> texcoords;
        std::vector<std::size_t> indices;
        std::vector<mesh_material> materials;

        _impl() = default;
        _impl(_impl &&) = delete;
    };

    std::shared_ptr<_impl> m_impl;

  public:
    // 注意这里必须创建一个指针，否则 m_impl 将为空
    mesh() : m_impl(std::make_shared<_impl>())
    {
    }

    _impl *operator->() const noexcept
    {
        return m_impl.get();
    }

    /**
     * @brief 从 obj 文件中读取三维网格数据
     *
     * @param[in] path
     * @param[in] scale
     */
    void read(std::string path, float scale = 1.0f);
};

} // namespace render

} // namespace xy
